package com.carcenter.store.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.carcenter.common.pojo.order.MonthSale;
import com.carcenter.common.pojo.personnel.StoreManager;

import com.carcenter.common.pojo.store.StoreDto;
import com.carcenter.common.result.Result;
import com.carcenter.common.pojo.store.MyPageData;
import com.carcenter.common.pojo.store.SearchStoreDto;
import com.carcenter.common.result.enums.impl.BusinessCode;
import com.carcenter.common.result.enums.impl.ResultCode;
import com.carcenter.store.entity.DefaultAddress;
import com.carcenter.store.entity.StoreInfo;
import com.carcenter.store.service.IStoreInfoService;
import com.carcenter.store.service.StoreAddressService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.order.client.OrderApi;
import com.personnel.client.StaffApi;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author car
 * @since 2025-07-16
 */
@RestController
@RequestMapping("/store-info")
public class StoreInfoController {

    @Autowired
    StaffApi staffApi;
    @Autowired
    OrderApi orderApi;

    @Autowired
    IStoreInfoService storeInfoService;

    @Autowired
    StoreAddressService storeAddressService;

    @Autowired
    private ObjectMapper objectMapper; // 注入Spring管理的ObjectMapper
    @Autowired
    RedisTemplate redisTemplate;



    @PostMapping("/getStoreList/{pageNum}/{pageSize}")
    public Result<MyPageData> getStoreList(
            @PathVariable Integer pageNum,
            @PathVariable Integer pageSize,
            @RequestBody(required = false) SearchStoreDto searchStoreDto) {

        // 1. 生成缓存键（基于搜索条件+分页信息）
        String cacheKey = generateCacheKey(pageNum, pageSize, searchStoreDto);

        // 2. 尝试从缓存获取数据
        MyPageData cachedData = (MyPageData) redisTemplate.opsForValue().get(cacheKey);
        if (cachedData != null) {
            return Result.ok(cachedData);
        }


        // 1. 初始化 storeIdList（处理员工名查询）
        List<Integer> storeIdList = new ArrayList<>();
        if (searchStoreDto != null
                && StringUtils.isNotBlank(searchStoreDto.getStaffName())) {
            Result storeIds = staffApi.getStoreIdsByStaffName(searchStoreDto.getStaffName());
            if (storeIds != null && storeIds.getCode() == ResultCode.SUCCESS.getCode()) {
                List<Integer> data1 =(List<Integer>) storeIds.getData();
                // 确保非null
                storeIdList=data1!=null?data1:new ArrayList<>();
            }

        }

        // 2. 构建动态查询条件
        LambdaQueryWrapper<StoreInfo> wrapper = Wrappers.lambdaQuery(StoreInfo.class);

        // 条件1：storeIdList 非空时限制范围
        if (storeIdList != null && !storeIdList.isEmpty()) {
            wrapper.in(StoreInfo::getId, storeIdList);
        }

        // 条件2：动态添加其他字段的模糊查询（非空时才生效）
        if (searchStoreDto != null) {
            if (StringUtils.isNotBlank(searchStoreDto.getStoreName())) {
                wrapper.like(StoreInfo::getStoreName, searchStoreDto.getStoreName());
            }
            if (StringUtils.isNotBlank(searchStoreDto.getBusinessStatus())) {
                wrapper.like(StoreInfo::getBusinessStatus, searchStoreDto.getBusinessStatus());
            }
            if (StringUtils.isNotBlank(searchStoreDto.getStoreType())) {
                wrapper.like(StoreInfo::getStoreType, searchStoreDto.getStoreType());
            }
        }

        // 3. 执行分页查询
        Page<StoreInfo> pageResult = storeInfoService.page(new Page<>(pageNum, pageSize), wrapper);

        List<StoreInfo> records = pageResult.getRecords();

        //需要优化，循环调用改成一次批量调用；批量补充StoreManager和3个销量类字段；
        // 需要优化的代码块（补充StoreManager和销量字段）
        if (records != null && records.size() > 0) {
            // 处理店长信息
            List<Integer> managerIds = records.stream()
                    .map(StoreInfo::getManagerId)
                    .collect(Collectors.toList());
            List<StoreManager> storeManagers = new ArrayList<>(); // 初始化为空集合（非null）
            Result<List<StoreManager>> ids = staffApi.getStoreManagersByManagerIds(managerIds);
            if (ids != null && ids.getCode() == ResultCode.SUCCESS.getCode()) {
                List<StoreManager> data2 = ids.getData();
                storeManagers = data2 != null ? data2 : new ArrayList<>(); // 确保非null
            }
            // 构建map时，无需再判断storeManagers是否为null
            HashMap<Integer, StoreManager> storeManagerHashMap = new HashMap<>();
            for (StoreManager storeManager : storeManagers) { // 若storeManagers为空集合，循环不执行
                if (storeManager != null && storeManager.getId() != null) { // 额外校验对象和主键非null
                    storeManagerHashMap.put(storeManager.getId(), storeManager);
                }
            }

            // 处理销量信息
            LocalDate now = LocalDate.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月");
            String thisMonth = now.format(formatter);
//            String thisMonth = "2025年06月";


            List<Integer> storeIds = records.stream().map(StoreInfo::getId).collect(Collectors.toList());
            List<MonthSale> monthSales = new ArrayList<>(); // 初始化为空集合（非null）
            Result<List<MonthSale>> result = orderApi.getMonthSalesByStoreIds(storeIds, thisMonth);
            if (result != null && result.getCode() == ResultCode.SUCCESS.getCode()) {
                List<MonthSale> data3 = result.getData();
                monthSales = data3 != null ? data3 : new ArrayList<>(); // 确保非null
            }
            // 构建map时，无需再判断monthSales是否为null
            HashMap<Integer, MonthSale> monthSaleHashMap = new HashMap<>();
            for (MonthSale monthSale : monthSales) { // 若monthSales为空集合，循环不执行
                if (monthSale != null && monthSale.getStoreId() != null) { // 额外校验对象和主键非null
                    monthSaleHashMap.put(monthSale.getStoreId(), monthSale);
                }
            }

            //获取各个门店的默认地址
            List<DefaultAddress> defaultAddressList = storeAddressService.getDefaultAddressListByStoreIds(storeIds);
            HashMap<Integer, DefaultAddress> defaultAddressHashMap = new HashMap<>();
            for (DefaultAddress defaultAddress : defaultAddressList) {
                if (defaultAddress != null && defaultAddress.getStoreId() != null) {
                    defaultAddressHashMap.put(defaultAddress.getStoreId(), defaultAddress);
                }
            }

            // 后续合并数据时，无需判断map是否为null（map初始化为new HashMap()，永远非null）
            for (StoreInfo record : records) {
                record.setStoreManager(storeManagerHashMap.get(record.getManagerId()));
                record.setMonthSale(monthSaleHashMap.get(record.getId()));
                record.setDefaultAddress(defaultAddressHashMap.get(record.getId()));
            }
        }

        // 4. 返回分页结果（注意：直接使用 pageResult.getRecords() 而不是 list()）
        MyPageData myPageData = new MyPageData(pageResult.getTotal(), records);

        redisTemplate.opsForValue().set(cacheKey, myPageData, 10, TimeUnit.MINUTES); // 缓存5分钟
        return Result.ok(myPageData);
    }


    // 生成缓存键的方法
    private String generateCacheKey(Integer pageNum, Integer pageSize, SearchStoreDto searchStoreDto) {
        StringBuilder keyBuilder = new StringBuilder("store:list:");
        keyBuilder.append("page=").append(pageNum)
                .append(":size=").append(pageSize);

        if (searchStoreDto != null) {
            // 将搜索条件转为JSON字符串并MD5哈希，避免键过长
            try {
                String conditionJson = objectMapper.writeValueAsString(searchStoreDto);
                String conditionHash = DigestUtils.md5DigestAsHex(conditionJson.getBytes());
                keyBuilder.append(":cond=").append(conditionHash);
            } catch (JsonProcessingException e) {
                // 序列化失败时，使用默认值
                keyBuilder.append(":cond=default");
            }
        }

        return keyBuilder.toString();
    }




    @GetMapping("/getStoreById/{storeId}")
    public Result<StoreInfo> getStoreById(@PathVariable int storeId) {
        StoreInfo storeInfo = storeInfoService.getById(storeId);
        return Result.ok(storeInfo);
    }


    @PostMapping("/newStore")
    public Result<StoreInfo> newStore(@RequestBody StoreInfo storeInfo) {
        storeInfoService.save(storeInfo);
        StoreInfo storeInfo1 = storeInfoService.getById(storeInfo.getId());
        return Result.ok(storeInfo1);
    }

    @PutMapping("/editStore")
    public Result<String> editStore(@RequestBody StoreInfo storeInfo) {

        storeInfoService.updateById(storeInfo);
        return Result.ok(BusinessCode.MODIFY_SUCCESS.getMessage());
    }


    @GetMapping("/getStoreIdsByStoreName")
    public Result<List<Integer>> getStoreIdsByStoreName(@RequestParam String storeName) {
        List<Integer> storeIds = storeInfoService.lambdaQuery()
                .like(StoreInfo::getStoreName, storeName)
                .select(StoreInfo::getId)
                .list() // 返回 List<Staff>（但只包含 storeId 字段）
                .stream()
                .map(StoreInfo::getId)
                .collect(Collectors.toList());
        return Result.ok(storeIds);
    }

    @PostMapping("/getStoreDtosByIds")
    public Result<List<StoreDto>> getStoreDtosByIds(@RequestBody List<Integer> storeIds) {
        List<StoreInfo> storeInfos = storeInfoService.listByIds(storeIds);
        List<StoreDto> storeDtos = new ArrayList<>();
        for (StoreInfo storeInfo : storeInfos) {
            StoreDto storeDto = new StoreDto();
            storeDto.setStoreId(storeInfo.getId());
            storeDto.setStoreName(storeInfo.getStoreName());
            storeDtos.add(storeDto);
        }
        return Result.ok(storeDtos);
    }

    @GetMapping("/getStore")
    public Result<List<StoreInfo>> getStore() {
        LambdaQueryWrapper<StoreInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(StoreInfo::getId, StoreInfo::getStoreName);
        List<StoreInfo> list = storeInfoService.list(wrapper);
        return Result.ok(list);
    }

    @GetMapping("/getStationCountByStoreId/{storeId}")
    public Result<Integer> getStationCountByStoreId(@PathVariable Integer storeId) {
        StoreInfo storeInfo = storeInfoService.getById(storeId);
        return Result.ok(storeInfo.getStationCount());
    }

}
